import path from "path";
import { checkDirExists, createDirectory, writeToFile } from "../../utils/tools";

export interface ICreateServiceParams {
  /**
   * 上级目录
   */
  superDir: string;

  /**
   * 模块名字（大驼峰）
   */
  moduleName: string;

  fields?: string[];
}

export function generServicesCode(params: ICreateServiceParams) {
  const modelName = `${params.moduleName}Model`;
  const entityName = `${params.moduleName}Entity`;
  const moduleInterface = `I${modelName}`;

  const tem = `import { IPageResponse } from "../../types/CommonType";
import { ValidationError } from "../../utils/errors";
import { getTreeStructure, readExcel, parseImportData } from "../../utils/tools";
import ${modelName} from "../../dao/model/${params.superDir}/${modelName}";
import ${entityName}, { ${moduleInterface}, importFieldMap } from "../../entities/${params.superDir}/${entityName}";


export class ${params.moduleName}Service {
  /**
   * 添加数据
   */
  public static async add(admin: ${entityName}): Promise<true> {
    // 1. 转换类型
    admin = ${entityName}.transform(admin);
    // 2. 数据验证
    const errors = await admin.validateThis();
    if (errors.length > 0) {
      throw new ValidationError(errors[0]);
    }

    await ${modelName}.create<${moduleInterface}>(admin);
    return true;
  }

  /**
   * 分页获取数据
   */
  public static async findByPage(offset: number, limit: number, where?): Promise<IPageResponse> {
    let data = await ${modelName}.findAndCountAll<${moduleInterface}>({
      offset: limit * (offset - 1),
      limit,
      where,
    });

    const result: IPageResponse = {
      total: data.count,
      list: data.rows.map((item) => item.dataValues),
    };

    return result;
  }

  public static async findByList(where = {}) {
    return ${modelName}.findAll<${moduleInterface}>({ where });
  }

  public static async findByTreeList(where: any = {}) {
    const result = await ${modelName}.findAll<${moduleInterface}>({ where });

    return getTreeStructure<${entityName}>(result.map((item) => item.dataValues));
  }

  /**
   * 通过id获取数据
   */
  public static async findById(id: string) {
    return ${modelName}.findByPk<${moduleInterface}>(id);
  }

  /**
   * 修改数据
   */
  public static async update(data: any) {
    return ${modelName}.update<${moduleInterface}>(data, {
      where: {
        id: data.id,
      },
    });
  }

  /**
   * 删除数据
   */
  public static async delete(id: string) {
    return ${modelName}.destroy({
      where: {
        id,
      },
    });
  }

  /**
   * 导入
   */
  public static async importData(filePath: string) {
    const data: any = readExcel(filePath);

    const result: any = [];
    for (let item of data) {
      item = ${entityName}.transform(item);
      // 2. 数据验证
      const errors = await item.validateThis();
      if (errors.length === 0) {
        result.push(item);
      }
    }
    await ${modelName}.bulkCreate(result);
    return result.length;
  }
}`;

  return tem;
}

export async function createService(params: ICreateServiceParams) {
  const codeText = generServicesCode(params);
  const filename = params.moduleName + "Service.ts";

  // 1. 找到存放service的文件
  const dirPath = path.resolve(__dirname, "../", params.superDir);
  if (!(await checkDirExists(dirPath))) {
    await createDirectory(dirPath);
  }

  // 生成实体类文件
  const target = path.resolve(dirPath, filename);
  await writeToFile(target, codeText);
}
